/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.bff.designtime.generator.core.sourceconfig.method;

import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bff.api.attribute.AbstractSourceConfig;
import com.inspur.edp.bff.api.manager.SourceConfig;
import com.inspur.edp.bff.api.manager.SourceType;
import com.inspur.edp.bff.designtime.generator.core.VmCoreGenContext;
import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import org.eclipse.jdt.core.dom.*;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

//protected List<SourceConfig> sourceConfigs {get;}
//protected string indexVoConfig = null;
public class SourceConfigCtorGenerator extends ClassMethodGenerator {

  private static final String beType = "GSPBusinessEntity";
  private static final String qoType = "QueryObject";
  private static final String SourceConfigsPropName = "sourceConfigs";
  private static final String IndexVoConfigPropName = "indexVoConfig";
  private VmCoreGenContext coreGenCtx;
  private String className;
  private String indexVoConfig;
  private java.util.ArrayList<SourceConfig> sourceConfigs = new java.util.ArrayList<SourceConfig>();

  public SourceConfigCtorGenerator(VmCoreGenContext coreGenCtx, String className) {
    super();
    this.coreGenCtx = coreGenCtx;
    this.className = className;
    initSourceConfigs();
//    initIndexVoConfig();
  }

  @Override
  protected String getMethodName() {
    return className;
  }

  @Override
  protected TypeInfo getReturnType() {
    return null;
  }

  @Override
  protected boolean buildIsConstructor() {
    return true;
  }

//  private void initIndexVoConfig() {
//    GspViewModel vo = coreGenCtx.getVmGenContext().getVm();
//    if (vo.getMainObject().getMapping()!=null  voNullable <.MainObject >.
//    Mapping != null && vo.MainObject.Mapping.SourceType == GspVoObjectSourceType.QoObject)
//    {
//      indexVoConfig = ((GspQoObjectMapping) vo.MainObject.Mapping).IndexVoId;
//    }
//		else
//    {
//      indexVoConfig = "";
//    }
//  }

  private void initSourceConfigs() {
    LinkedHashMap<String, GspMetadata> entities = coreGenCtx.getVmGenContext()
        .getRefEntityCollection();
    if (entities != null && entities.size() > 0) {
      for (Map.Entry<String, GspMetadata> entity : entities.entrySet()) {
        switch (entity.getValue().getHeader().getType()) {
          case beType:
            sourceConfigs.add(getBeSourceConfig(entity.getValue()));
            break;
            //Java版临时注释：QO
//          case qoType:
//            sourceConfigs.add(GetQoSourceConfig(entity.getValue()));
//            break;
          default:
            throw new RuntimeException("无效的元数据类型{"+entity.getValue().getHeader().getType()+"}");
        }
      }
    }
  }

  private SourceConfig getBeSourceConfig(GspMetadata metadata) {
    SourceConfig tempVar = new SourceConfig();
    tempVar.setSourceConfigId (((GspBusinessEntity) metadata.getContent()).getGeneratedConfigID());
    tempVar.setSourceType(com.inspur.edp.bff.api.manager.SourceType.Be);
    SourceConfig sourceConfig = tempVar;
    return sourceConfig;
  }

//  private SourceConfig getQoSourceConfig(GspMetadata metadata) {
//    SourceConfig tempVar = new SourceConfig();
//    tempVar.SourceConfigId = ((QueryObject) metadata.Content).GetConfigID();
//    tempVar.SourceType = SourceType.Qo;
//    SourceConfig sourceConfig = tempVar;
//    return sourceConfig;
//  }

  //C# TO JAVA CONVERTER TODO TASK: Lambda expressions and anonymous methods are not converted by C# to Java Converter:
  @Override
  protected java.util.ArrayList<Modifier.ModifierKeyword> getAccessModifiers() {
    return new java.util.ArrayList<Modifier.ModifierKeyword>(
        java.util.Arrays.asList(new Modifier.ModifierKeyword[]{Modifier.ModifierKeyword.PUBLIC_KEYWORD}));
  }

  @Override
  protected ArrayList<ParameterInfo> getParameterCollection() {
    return null;
  }

  @Override
  protected Block buildMethodBody() {
    Block block=ast.newBlock();
    addInitVal(block);
    addSetSourceConfigs(block);
    return block;
  }

  private void addInitVal(Block block) {
    VariableDeclarationFragment variableDeclarationFragment=ast.newVariableDeclarationFragment();
    variableDeclarationFragment.setName(ast.newSimpleName("val"));
    variableDeclarationFragment.setInitializer(ast.newNullLiteral());
    VariableDeclarationStatement variableDeclarationStatement=ast.newVariableDeclarationStatement(variableDeclarationFragment);
    variableDeclarationStatement.setType(new TypeInfo(SourceConfig.class).getType(ast,coreGenCtx));
    block.statements().add(variableDeclarationStatement);
  }

  private void addSetSourceConfigs(Block block) {
    if (sourceConfigs.size() == 0)
      return;
    for (SourceConfig sourceConfig : sourceConfigs)
    {
      addNewVal(sourceConfig,block);
      addSetSourceConfigID(sourceConfig,block);
      addSetSourceConfigType(sourceConfig,block);
      addToSourceConfigs(sourceConfig,block);
    }
  }

  private void addNewVal(SourceConfig sourceConfig, Block block) {
    Assignment assignment=ast.newAssignment();
    assignment.setLeftHandSide(ast.newSimpleName("val"));
    assignment.setOperator(Assignment.Operator.ASSIGN);
    ClassInstanceCreation classInstanceCreation=ast.newClassInstanceCreation();
    classInstanceCreation.setType(new TypeInfo(SourceConfig.class).getType(ast, coreGenCtx));
    assignment.setRightHandSide(classInstanceCreation);

    block.statements().add(ast.newExpressionStatement(assignment));
  }

  private void addSetSourceConfigID(SourceConfig sourceConfig, Block block)
  {
    MethodInvocation methodInvocation=ast.newMethodInvocation();
    methodInvocation.setExpression(ast.newSimpleName("val"));
    methodInvocation.setName(ast.newSimpleName("setSourceConfigId"));
    StringLiteral stringLiteral=ast.newStringLiteral();
    stringLiteral.setLiteralValue(sourceConfig.getSourceConfigId());
    methodInvocation.arguments().add(stringLiteral);
    block.statements().add(ast.newExpressionStatement(methodInvocation));
  }

  private void addSetSourceConfigType(SourceConfig sourceConfig, Block block)
  {
    MethodInvocation methodInvocation=ast.newMethodInvocation();
    methodInvocation.setExpression(ast.newSimpleName("val"));
    methodInvocation.setName(ast.newSimpleName("setSourceType"));
    methodInvocation.arguments().add(ast.newQualifiedName(ast.newName(SourceType.class.getTypeName()),ast.newSimpleName("Be")));

    block.statements().add(ast.newExpressionStatement(methodInvocation));
  }

  private void addToSourceConfigs(SourceConfig sourceConfig, Block block)
  {
    MethodInvocation methodInvocation=ast.newMethodInvocation();
    methodInvocation.setName(ast.newSimpleName("add"));

    MethodInvocation methodInvocationExpression=ast.newMethodInvocation();
    methodInvocationExpression.setName(ast.newSimpleName("getSourceConfigs"));
    methodInvocation.setExpression(methodInvocationExpression);

    methodInvocation.arguments().add(ast.newSimpleName("val"));
    block.statements().add(ast.newExpressionStatement(methodInvocation));
  }
}
